package com.guang.dubbo.shoulu.v1.framework;

import com.guang.dubbo.shoulu.v1.framework.web.HttpClient;
import com.guang.dubbo.shoulu.v1.framework.web.RemoteMapRegister;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;


public class ProxyFactory<T> {
    @SuppressWarnings("unchecked")
    public static <T> T getProxy(final Class interfaceClass) {
        return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{interfaceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 针对于未开发完成的接口进行mock
                String mock = System.getProperty("mock");
                if (mock != null && mock.startsWith("return:")) {
                    String result = mock.replace("return:", "");
                    return result;
                }

                // TODO 重试次数应该有用户自己来进行指定
                int retryCount = 0;
                while (retryCount < 3) {
                    try {
                        // 组装调用参数信息
                        Invocation invocation = new Invocation(interfaceClass.getName(), method.getName(), args, method.getParameterTypes());
                        // 从注册列表获取得到对应的Ip和端口号，存在着多个的时候，那么就可以从这里随机获取得到一个可用的服务提供者来进行使用
                        List<URL> urls = RemoteMapRegister.get(interfaceClass.getName());
                        // TODO 负载均衡算法进行实现，这里应该选择用户的使用的负载均衡使用方式进行实现。当前使用简单版本随机的方式进行实现
                        URL url = LoadBalance.random(urls);
                        // 如果说重试之后，依然无用，那么下一次的选择的时候就不应该再次选择到相同的服务提供者上来

                        // 在这里来进行配置根据什么协议来进行使用
                        String protocolStr = System.getProperty("protocol");
                        Protocol protocol = ProtocolFactory.getProtocol(protocolStr);
                        String result = protocol.send(url, invocation);
                        return result;
                    } catch (Exception e) {
                        retryCount++;
                    }
                }
                return "哟呵，当前调用有点问题，请稍后再试";
            }
        });
    }
}
